#ifndef CREFLECTION_H
#define CREFLECTION_H

#include <QObject>

/*
Qt提供的元对象反射的思考和使用总结:
1, property理解为一个对象的属性, 属性可以通过对象 + 属性的名称字符串进行获取(get)和改变(set);
2, Q_INVOKABLE 宏修饰的成员函数可以通过对象 + 函数名字符串进行调用;
3, 通过对象 + 函数名字符串进行调用函数可以应用到很多场景, 比如 一个vector容器中存储了多个类对象的指针, 多个类对象里都有一个函数名叫做 func1(),
    但是这些类都不是派生类或者继承自同一个基类, 此时可以通过函数对象 + 函数名字符串的方式进行多个类对象的调用.
4, 应用场景: (其实是我一直想要搞懂的地方，反射这个机制到底在哪些场景下使用起来能解决实际问题和痛点呢?)
    1) 跨语言调用场景: 比如需要动态语言调用静态语言的时候, js调用C++的方法, 通过传递函数名字符串进来实现对实际的类中方法进行调用, 常见于C++与浏览器中的js互相调用的场景;
    2) 在一个函数中需要调用多个类的方法时, 是否可以尝试使用 Map<Obj, funcName> 的方式, 然后使用 for循环遍历此 map 然后使用 invokeMethod 的方式进行调用.
        - 补充 2), 实际应用中可以使用 Map<className, Obj> 的方式存储对象的类名称+对象实体, 与web端约定调用接口, 比如 ProjectName.ClassName.FuncName(arg1, arg2...)的方式实现反射调用;
    3) 反射工厂, 实际ClassName这个字符串也可以用作创建类对象的关键字,
*/

class CReflection : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString refNameVal MEMBER m_strRefNameVal READ getName WRITE setName NOTIFY sig_nameTextChange)
public:
    explicit CReflection(QObject *parent = nullptr);

signals:
    void sig_nameTextChange();


public slots:
    void on_sigNameTextChange();

public:
    Q_INVOKABLE void func1();

    Q_INVOKABLE QString getName();
    Q_INVOKABLE void setName(const QString& text);

public:
    QString m_strRefNameVal;
};

#endif // CREFLECTION_H
